package com.fancy.user.service.impl;

import cn.hutool.db.PageResult;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fancy.common.dto.response.Result;
import com.fancy.imasclient.dto.*;
import com.fancy.user.dto.request.*;
import com.fancy.user.dto.response.*;
import com.fancy.user.entity.User;
import com.fancy.user.entity.UserExperience;
import com.fancy.user.entity.UserMembership;
import com.fancy.user.entity.UserLevel;
import com.fancy.user.entity.MembershipType;
import com.fancy.user.mapper.UserMapper;
import com.fancy.user.mapper.UserExperienceMapper;
import com.fancy.user.mapper.UserMembershipMapper;
import com.fancy.user.mapper.UserLevelMapper;
import com.fancy.user.mapper.MembershipTypeMapper;
import com.fancy.user.service.UserService;
import com.fancy.user.utils.JwtUtils;
import com.fancy.imasclient.client.PlaylistServiceClient;
import com.fancy.imasclient.client.SocialServiceClient;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@Transactional
@RequiredArgsConstructor
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    private final SocialServiceClient socialServiceClient;
    private final PlaylistServiceClient playlistServiceClient;
    private final UserExperienceMapper userExperienceMapper;
    private final UserMembershipMapper userMembershipMapper;
    private final UserLevelMapper userLevelMapper;
    private final MembershipTypeMapper membershipTypeMapper;
    private final PasswordEncoder passwordEncoder;
    private final JwtUtils jwtUtils;

    @Override
    public Result<UserRegisterResponseVO> register(UserRegisterRequestDTO dto) {
        // 1. 检查用户名或邮箱是否已存在
        if (existsByUsername(dto.getUsername()) || existsByEmail(dto.getEmail())) {
            return Result.fail("用户名或邮箱已被占用");
        }

        System.out.println("dto: " + dto);
        // 2. 转换DTO到Entity
        User user = new User();
        BeanUtils.copyProperties(dto, user);
        // 加密密码
        user.setPassword(passwordEncoder.encode(dto.getPassword()));
        System.out.println("user: " + user);
        user.setCreateTime(LocalDateTime.now());
        user.setUpdateTime(LocalDateTime.now());
        user.setStatus(1); // 默认启用状态

        // 3. 保存用户
        int result = baseMapper.insert(user);
        if (result <= 0) {
            return Result.fail("注册失败");
        }

        // 4. 初始化用户经验记录
        userExperienceMapper.initUserExperience(user.getUserId());

        // 5. 构建响应
        UserRegisterResponseVO response = new UserRegisterResponseVO();
        response.setUserId(user.getUserId());
        response.setUsername(user.getUsername());
        response.setNickname(user.getNickname());
        response.setAvatarUrl(user.getAvatarUrl());
        response.setCreateTime(Date.from(user.getCreateTime().atZone(ZoneId.systemDefault()).toInstant()));

        return Result.success(response);
    }

    private boolean existsByUsername(String username) {
        return count(new QueryWrapper<User>().eq("username", username)) > 0;
    }

    private boolean existsByEmail(String email) {
        return count(new QueryWrapper<User>().eq("email", email)) > 0;
    }

    @Override
    public Result<UserLoginResponseVO> login(UserLoginRequestDTO dto) {
        // 1. 查询用户
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.eq("username", dto.getUsernameOrEmail())
               .or()
               .eq("email", dto.getUsernameOrEmail());

        User user = getOne(wrapper);
        if (user == null) {
            return Result.fail("用户名/邮箱不存在");
        }

        // 2. 验证密码
        if (!passwordEncoder.matches(dto.getPassword(), user.getPassword())) {
            return Result.fail("密码错误");
        }

        // 3. 检查用户状态
        if (user.getStatus() == 0) {
            return Result.fail("账户已被禁用，请联系管理员");
        }

        // 4. 更新登录信息
        user.setLastLoginTime(LocalDateTime.now());
        user.setLoginIp(dto.getClientIp());
        updateById(user);

        // 5. 获取用户等级和经验信息
        UserExperience userExperience = userExperienceMapper.selectOne(
            new QueryWrapper<UserExperience>().eq("user_id", user.getUserId())
        );

        // 6. 获取用户会员信息
        QueryWrapper<UserMembership> membershipWrapper = new QueryWrapper<>();
        membershipWrapper.eq("user_id", user.getUserId())
                        .eq("status", 1)
                        .gt("end_time", LocalDateTime.now());
        UserMembership userMembership = userMembershipMapper.selectOne(membershipWrapper);

        String membershipType = "FREE";
        if (userMembership != null) {
            MembershipType type = membershipTypeMapper.selectById(userMembership.getMembershipTypeId());
            if (type != null) {
                membershipType = type.getTypeCode();
            }
        }

        // 7. 生成JWT token
        String token = jwtUtils.generateToken(user.getUserId(), user.getUsername(), "USER");
        long expireTime = System.currentTimeMillis() + 86400000; // 24小时有效期

        // 8. 构建响应
        UserLoginResponseVO response = new UserLoginResponseVO();
        response.setToken(token);
        response.setExpireTime(expireTime);

        UserLoginResponseVO.UserInfo userInfo = new UserLoginResponseVO.UserInfo();
        userInfo.setUserId(user.getUserId());
        userInfo.setUsername(user.getUsername());
        userInfo.setNickname(user.getNickname());
        userInfo.setAvatarUrl(user.getAvatarUrl());
        userInfo.setLevel(userExperience != null ? userExperience.getCurrentLevel() : 1);
        userInfo.setExp(userExperience != null ? userExperience.getCurrentExp() : 0);
        userInfo.setMembershipType(membershipType);

        response.setUserInfo(userInfo);
        
        return Result.success(response);
    }

    @Override
    public Result<UserDetailVO> getUserInfo(Long userId) {
        User user = getById(userId);
        if (user == null) {
            return Result.fail("用户不存在");
        }

        UserDetailVO response = new UserDetailVO();
        BeanUtils.copyProperties(user, response);

        // 设置等级信息
        UserExperience userExperience = userExperienceMapper.selectOne(new QueryWrapper<UserExperience>().eq("user_id", userId));
        if (userExperience != null) {
            UserDetailVO.LevelInfo levelInfo = new UserDetailVO.LevelInfo();
            levelInfo.setCurrentLevel(userExperience.getCurrentLevel());
            levelInfo.setCurrentExp(userExperience.getCurrentExp());
            UserLevel currentLevel = userLevelMapper.selectById(userExperience.getCurrentLevel());
            if (currentLevel != null) {
                levelInfo.setLevelName(currentLevel.getLevelName());
                levelInfo.setRequiredExp(currentLevel.getMaxExp());
            }
            response.setLevelInfo(levelInfo);
        }

        // 设置会员信息
        UserMembership userMembership = userMembershipMapper.selectOne(new QueryWrapper<UserMembership>().eq("user_id", userId).eq("status", 1));
        if (userMembership != null) {
            UserDetailVO.MembershipInfo membershipInfo = new UserDetailVO.MembershipInfo();
            MembershipType membershipType = membershipTypeMapper.selectById(userMembership.getMembershipTypeId());
            if (membershipType != null) {
                membershipInfo.setType(membershipType.getTypeCode());
                membershipInfo.setTypeName(membershipType.getTypeName());
            }
            // 修改第164行代码为：
            membershipInfo.setEndTime(Date.from(userMembership.getEndTime().atZone(ZoneId.systemDefault()).toInstant()));
            membershipInfo.setStatus(userMembership.getStatus());
            response.setMembershipInfo(membershipInfo);
        }

        // 设置统计信息
        UserDetailVO.StatisticsInfo statisticsInfo = new UserDetailVO.StatisticsInfo();
        Result<Map<String, Object>> statsResult = socialServiceClient.getFollowStats(userId, userId);
        if (statsResult.isSuccess() && statsResult.getData() != null) {
            Map<String, Object> statsData = statsResult.getData();
            statisticsInfo.setFollowingCount((Integer) statsData.getOrDefault("followingCount", 0));
            statisticsInfo.setFollowerCount((Integer) statsData.getOrDefault("followerCount", 0));
        }

        Result<Integer> collectionCountResult = playlistServiceClient.getCollectionCount(userId);
        if (collectionCountResult.isSuccess()) {
            statisticsInfo.setCollectionCount(collectionCountResult.getData());
        }
        response.setStatisticsInfo(statisticsInfo);

        return Result.success(response);
    }

    @Override
    public Result<Void> updateUserInfo(Long userId, UserUpdateRequestDTO dto) {
        User user = getById(userId);
        if (user == null) {
            return Result.fail("用户不存在");
        }

        // 更新允许的字段
        if (dto.getNickname() != null) {
            user.setNickname(dto.getNickname());
        }
        if (dto.getAvatarUrl() != null) {
            user.setAvatarUrl(dto.getAvatarUrl());
        }
        if (dto.getGender() != null) {
            user.setGender(dto.getGender());
        }
        if (dto.getBirthday() != null) {
            user.setBirthday(LocalDate.parse(dto.getBirthday()).atStartOfDay());
        }
        if (dto.getIntroduction() != null) {
            user.setIntroduction(dto.getIntroduction());
        }
        if (dto.getHobby() != null) {
            user.setHobby(dto.getHobby());
        }

        user.setUpdateTime(LocalDateTime.now());
        updateById(user);

        return Result.success(null);
    }

    @Override
    public Result<MembershipPurchaseResponseVO> purchaseMembership(Long userId, MembershipPurchaseRequestDTO dto) {
        // 1. 验证用户存在
        User user = getById(userId);
        if (user == null) {
            return Result.fail("用户不存在");
        }

        // 2. ���证会员类型
        MembershipType membershipType = membershipTypeMapper.selectByTypeCode(dto.getMembershipTypeCode());
        if (membershipType == null) {
            return Result.fail("会员类型不存在");
        }

        // 3. 处理现有会员
        userMembershipMapper.expireUserMembership(userId);

        // 4. 创建新会员记录
        UserMembership userMembership = new UserMembership();
        userMembership.setUserId(userId);
        userMembership.setMembershipTypeId(membershipType.getTypeId());
        userMembership.setStartTime(LocalDateTime.now());
        userMembership.setEndTime(LocalDateTime.now().plusDays(membershipType.getDurationDays()));
        userMembership.setStatus(1);
        userMembership.setOrderId(dto.getOrderId());
        userMembership.setCreateTime(LocalDateTime.now());

        userMembershipMapper.insert(userMembership);

        // 5. 构建响应
        MembershipPurchaseResponseVO response = new MembershipPurchaseResponseVO();
        response.setOrderId(userMembership.getOrderId());
        response.setMembershipType(membershipType.getTypeCode());
        response.setStartTime(userMembership.getStartTime());
        response.setEndTime(userMembership.getEndTime());

        return Result.success(response);
    }

    //
    @Override
    public Result<PageResult<UserCollectionResponseDTO>> getUserCollections(Long userId, Integer type, int page, int size) {
        // 调用播放列表服务获取收藏信息
        Result<PageResult<UserCollectionResponseDTO>> result = playlistServiceClient.getUserCollections(userId, type, page, size);
        return result;
    }

    @Override
    public Result<Void> followTarget(Long userId, FollowRequestDTO dto) {
        // 调用社交服务处理关注逻辑
        return socialServiceClient.followTarget(userId, dto);
    }

    @Override
    public Result<Void> unfollowTarget(Long userId, FollowRequestDTO dto) {
        // 调用社交服务处理取消关注逻辑
        return socialServiceClient.unfollowTarget(userId, dto);
    }

    @Override
    public Result<PageResult<FollowInfoDTO>> getFollowing(Long userId, int page, int size) {
        // 调用社交服务获取关注列表
        return socialServiceClient.getFollowing(userId, page, size);
    }

    @Override
    public Result<PageResult<FollowInfoDTO>> getFollowers(Long userId, int page, int size) {
        // 调用社交服务获取粉丝列表
        return socialServiceClient.getFollowers(userId, page, size);
    }

    @Override
    public UserBasicInfo getUserBasicInfo(Long userId) {
        User user = getById(userId);
        if (user == null) {
            return null;
        }

        UserBasicInfo userBasicInfo = new UserBasicInfo();
        userBasicInfo.setUserId(userId);
        userBasicInfo.setUsername(user.getUsername());
        userBasicInfo.setNickname(user.getNickname());
        userBasicInfo.setAvatarUrl(user.getAvatarUrl());

        return userBasicInfo;
    }

    @Override
    public boolean existsById(Long userId) {
        return getById(userId) != null;
    }

    @Override
    public Map<Long, UserBasicInfo> getUsersBasicInfoBatch(List<Long> userIds) {
        List<User> users = listByIds(userIds);
        return users.stream()
                .collect(Collectors.toMap(
                        User::getUserId,
                        user -> {
                            UserBasicInfo userBasicInfo = new UserBasicInfo();
                            userBasicInfo.setUserId(user.getUserId());
                            userBasicInfo.setUsername(user.getUsername());
                            userBasicInfo.setNickname(user.getNickname());
                            userBasicInfo.setAvatarUrl(user.getAvatarUrl());
                            return userBasicInfo;
                        }
                ));
    }

    /**
     * 增加用户经验值
     * @param userId 用户ID
     * @param expValue 经验值
     */
    public void addUserExperience(Long userId, Integer expValue) {
        // 1. 获取当前用户经验
        UserExperience userExperience = userExperienceMapper.selectOne(
                new QueryWrapper<UserExperience>().eq("user_id", userId));

        if (userExperience == null) {
            // 初始化用户经验记录
            userExperienceMapper.initUserExperience(userId);
            userExperience = userExperienceMapper.selectOne(
                    new QueryWrapper<UserExperience>().eq("user_id", userId));
        }

        // 2. 获取会员加���
        UserMembership currentMembership = userMembershipMapper.getCurrentMembership(userId);
        double multiplier = 1.0;
        if (currentMembership != null) {
            MembershipType membershipType = membershipTypeMapper.selectById(currentMembership.getMembershipTypeId());
            if (membershipType != null) {
                multiplier = membershipType.getExpMultiplier().doubleValue();
            }
        }

        // 3. 计算实际增加的经验值
        int actualExpValue = (int) (expValue * multiplier);

        // 4. 更新经验值
        userExperienceMapper.addUserExp(userId, actualExpValue);

        // 5. 检查是否需要升级
        int newTotalExp = userExperience.getTotalExp() + actualExpValue;
        UserLevel newLevel = userLevelMapper.selectLevelByExp(newTotalExp);
        if (newLevel != null && !newLevel.getLevelId().equals(userExperience.getCurrentLevel())) {
            userExperienceMapper.updateUserLevel(userId, newLevel.getLevelId());
        }
    }

    /**
     * 检查并更新过期的会员
     */
    @Transactional
    public void updateExpiredMemberships() {
        userMembershipMapper.updateExpiredMemberships(LocalDateTime.now());
    }

    @Override
    public Result<List<MembershipTypeResponseVO>> getMembershipTypes() {
        // 获取所有启用的会员类型
        List<MembershipType> membershipTypes = membershipTypeMapper.selectAllEnabled();

        // 转换为响应DTO
        List<MembershipTypeResponseVO> responseList = membershipTypes.stream()
                .map(this::convertToMembershipTypeResponseVO)
                .collect(Collectors.toList());

        return Result.success(responseList);
    }

    @Override
    public Result<MembershipTypeDetailVO> getMembershipTypeDetail(String typeCode) {
        // 根据类型编码查询会员类型
        MembershipType membershipType = membershipTypeMapper.selectByTypeCode(typeCode);
        if (membershipType == null) {
            return Result.fail("会员类型不存在");
        }

        // 转换为详情DTO
        MembershipTypeDetailVO detailVO = convertToMembershipTypeDetailVO(membershipType);

        return Result.success(detailVO);
    }

    /**
     * 转换MembershipType为MembershipTypeResponseVO
     */
    private MembershipTypeResponseVO convertToMembershipTypeResponseVO(MembershipType membershipType) {
        MembershipTypeResponseVO vo = new MembershipTypeResponseVO();
        vo.setTypeId(membershipType.getTypeId());
        vo.setTypeName(membershipType.getTypeName());
        vo.setTypeCode(membershipType.getTypeCode());
        vo.setDescription(membershipType.getDescription());
        vo.setPrice(membershipType.getPrice());
        vo.setDurationDays(membershipType.getDurationDays());
        vo.setExpMultiplier(membershipType.getExpMultiplier());

        // 解析权益信息
        List<String> privilegeList = parsePrivileges(membershipType.getPrivileges());
        vo.setPrivilegeList(privilegeList);

        // 设置推荐和热门标记
        vo.setIsRecommended("VIP".equals(membershipType.getTypeCode()));
        vo.setIsPopular("PLATINUM".equals(membershipType.getTypeCode()));

        // 设置折扣信息（如果有的话）
        if (membershipType.getPrice().compareTo(BigDecimal.valueOf(20)) > 0) {
            MembershipTypeResponseVO.DiscountInfo discountInfo = new MembershipTypeResponseVO.DiscountInfo();
            discountInfo.setOriginalPrice(membershipType.getPrice().multiply(BigDecimal.valueOf(1.2)));
            discountInfo.setDiscountRate(BigDecimal.valueOf(0.83));
            discountInfo.setDiscountLabel("限时优惠");
            vo.setDiscountInfo(discountInfo);
        }

        return vo;
    }

    /**
     * 转换MembershipType为MembershipTypeDetailVO
     */
    private MembershipTypeDetailVO convertToMembershipTypeDetailVO(MembershipType membershipType) {
        MembershipTypeDetailVO vo = new MembershipTypeDetailVO();
        vo.setTypeId(membershipType.getTypeId());
        vo.setTypeName(membershipType.getTypeName());
        vo.setTypeCode(membershipType.getTypeCode());
        vo.setDescription(membershipType.getDescription());
        vo.setPrice(membershipType.getPrice());
        vo.setDurationDays(membershipType.getDurationDays());
        vo.setExpMultiplier(membershipType.getExpMultiplier());

        // 构建详细权益信息
        List<MembershipTypeDetailVO.PrivilegeDetail> privilegeDetails = buildPrivilegeDetails(membershipType);
        vo.setPrivilegeDetails(privilegeDetails);

        // 构建对比信息
        List<MembershipTypeDetailVO.ComparisonInfo> comparisonInfos = buildComparisonInfos(membershipType);
        vo.setComparisonInfos(comparisonInfos);

        // 设置购买建议和适用人群
        vo.setPurchaseAdvice(getPurchaseAdvice(membershipType.getTypeCode()));
        vo.setTargetAudience(getTargetAudience(membershipType.getTypeCode()));

        return vo;
    }

    /**
     * 解析权益信息
     */
    private List<String> parsePrivileges(String privileges) {
        List<String> privilegeList = new ArrayList<>();
        if (privileges != null) {
            try {
                // 这里简化处理，实际可以使用JSON解析
                if (privileges.contains("daily_play_limit")) {
                    privilegeList.add("无限制播放");
                }
                if (privileges.contains("ad_free")) {
                    privilegeList.add("去广告");
                }
                if (privileges.contains("high_quality")) {
                    privilegeList.add("高品质音频");
                }
                if (privileges.contains("download")) {
                    privilegeList.add("离线下载");
                }
                if (privileges.contains("early_access")) {
                    privilegeList.add("新歌抢先听");
                }
            } catch (Exception e) {
                // 解析失败时的默认权益
                privilegeList.add("基础音乐服务");
            }
        }
        return privilegeList;
    }

    /**
     * 构建详细权益信息
     */
    private List<MembershipTypeDetailVO.PrivilegeDetail> buildPrivilegeDetails(MembershipType membershipType) {
        List<MembershipTypeDetailVO.PrivilegeDetail> details = new ArrayList<>();

        switch (membershipType.getTypeCode()) {
            case "NORMAL":
                details.add(createPrivilegeDetail("基础播放", "每日20首歌曲播放限制", "/icons/play.png", false));
                details.add(createPrivilegeDetail("标准音质", "128kbps音质播放", "/icons/quality.png", false));
                break;
            case "VIP":
                details.add(createPrivilegeDetail("无限播放", "无播放次数限制", "/icons/unlimited.png", true));
                details.add(createPrivilegeDetail("去除广告", "享受无广告音乐体验", "/icons/no-ads.png", true));
                details.add(createPrivilegeDetail("高品质音频", "320kbps高品质音频", "/icons/hq.png", true));
                details.add(createPrivilegeDetail("离线下载", "支持歌曲离线下载", "/icons/download.png", false));
                break;
            case "PLATINUM":
                details.add(createPrivilegeDetail("无限播放", "无播放次数限制", "/icons/unlimited.png", true));
                details.add(createPrivilegeDetail("去除广告", "享受无广告音乐体验", "/icons/no-ads.png", false));
                details.add(createPrivilegeDetail("无损音质", "FLAC无损音质播放", "/icons/lossless.png", true));
                details.add(createPrivilegeDetail("离线下载", "支持歌曲离线下载", "/icons/download.png", false));
                details.add(createPrivilegeDetail("新歌抢先听", "独家新歌提前收听", "/icons/early.png", true));
                details.add(createPrivilegeDetail("专属客服", "7x24小时专属客服", "/icons/vip-service.png", true));
                break;
        }

        return details;
    }

    /**
     * 创建权益详情
     */
    private MembershipTypeDetailVO.PrivilegeDetail createPrivilegeDetail(String name, String description, String icon, boolean isHighlight) {
        MembershipTypeDetailVO.PrivilegeDetail detail = new MembershipTypeDetailVO.PrivilegeDetail();
        detail.setPrivilegeName(name);
        detail.setPrivilegeDescription(description);
        detail.setPrivilegeIcon(icon);
        detail.setIsHighlight(isHighlight);
        return detail;
    }

    /**
     * 构建对比信息
     */
    private List<MembershipTypeDetailVO.ComparisonInfo> buildComparisonInfos(MembershipType membershipType) {
        List<MembershipTypeDetailVO.ComparisonInfo> comparisons = new ArrayList<>();

        switch (membershipType.getTypeCode()) {
            case "VIP":
                comparisons.add(createComparisonInfo("播放限制", "无限制", "普通用户20首/天", true));
                comparisons.add(createComparisonInfo("音质", "320kbps", "普通用户128kbps", true));
                comparisons.add(createComparisonInfo("广告", "无广告", "普通用户有广告", true));
                comparisons.add(createComparisonInfo("离线下载", "支持", "普通用户不支持", true));
                break;
            case "PLATINUM":
                comparisons.add(createComparisonInfo("播放限制", "无限制", "VIP无限制", false));
                comparisons.add(createComparisonInfo("音质", "FLAC无损", "VIP 320kbps", true));
                comparisons.add(createComparisonInfo("新歌", "抢先听", "VIP同步更新", true));
                comparisons.add(createComparisonInfo("客服", "专属7x24", "VIP普通客服", true));
                break;
        }

        return comparisons;
    }

    /**
     * 创建对比信息
     */
    private MembershipTypeDetailVO.ComparisonInfo createComparisonInfo(String itemName, String currentValue, String otherValue, boolean isAdvantage) {
        MembershipTypeDetailVO.ComparisonInfo info = new MembershipTypeDetailVO.ComparisonInfo();
        info.setItemName(itemName);
        info.setCurrentValue(currentValue);
        info.setOtherValue(otherValue);
        info.setIsAdvantage(isAdvantage);
        return info;
    }

    /**
     * 获取购买建议
     */
    private String getPurchaseAdvice(String typeCode) {
        switch (typeCode) {
            case "VIP":
                return "适合经常听音乐的用户，享受无广告和高品质音乐体验";
            case "PLATINUM":
                return "适合音质要求极高的发烧友，享受无损音质和独家权益";
            default:
                return "免费用户，可体验基础音乐功能";
        }
    }

    /**
     * 获取适用人群
     */
    private String getTargetAudience(String typeCode) {
        switch (typeCode) {
            case "VIP":
                return "音乐爱好者、上班族、学生群体";
            case "PLATINUM":
                return "音乐发烧友、专业音乐工作者、高端用户";
            default:
                return "初次体验用户、轻度音乐听众";
        }
    }
}
